﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Artemis.Core;
using System.Data.Common;
using System.Data;
using System.Text.RegularExpressions;
using System.Configuration;

namespace Artemis.Data.ProxyProvider
{
    public sealed class ProxyConnection : DbConnectionWrapper
    {
        ConnectionState _state;
        internal DbConnection ActualConnection { get; private set; }
        internal string ServerGroupName { get; private set; }
        public override void Open()
        {
            _state = ConnectionState.Open;
        }

        public override void Close()
        {
            _state = ConnectionState.Closed;
            base.Close();
        }

        internal void OpenWrappedConnection() { base.Open(); }

        public override System.Data.ConnectionState State
        {
            get
            {
                return _state;// return base.State;
            }
        }

        /// <summary>
        /// Initializes a new instance of the EFCachingConnection class.
        /// </summary>
        public ProxyConnection()
            : this(null)
        {

        }

        public override DbConnection WrappedConnection
        {
            get
            {
                return base.WrappedConnection;
            }
            set
            {
                base.WrappedConnection = value;
                if (value != null)
                {
                    ActualConnection = GetActualDbConnection(value);
                    ServerGroupName = GetServerGroupName(ActualConnection.ConnectionString);
                }
            }
        }

        /// <summary>
        /// Initializes a new instance of the EFCachingConnection class.
        /// </summary>
        /// <param name="wrappedConnection">The wrapped connection.</param>
        public ProxyConnection(DbConnection wrappedConnection)
        {
            this.WrappedConnection = wrappedConnection;

        }

        protected override string DefaultWrappedProviderName
        {
            get { return ProxyConfiguration.DefaultWrappedProvider; }
        }

        protected override DbCommand CreateDbCommand() {
            var wrapCmd = WrappedConnection.CreateCommand();
            wrapCmd.Connection = WrappedConnection;
            var define = new ProxyCommandDefinition();
            var cmd = new ProxyCommand(wrapCmd, define);
            cmd.Connection = this;
            return cmd;
        }
        private DbConnection GetActualDbConnection(DbConnection wrappedConnection)
        {
            var con = wrappedConnection;
            var wrap = wrappedConnection as DbConnectionWrapper;
            while (wrap != null)
            {
                con = wrap.WrappedConnection;
                wrap = con as DbConnectionWrapper;
            }
            return con;
        }

        static readonly Regex _regx = new Regex(@"\((?<group>\w+)\)");
        private string GetServerGroupName(string connectionString)
        {
            var m = _regx.Match(connectionString);
            if (!m.Success)
                return string.Empty;
            return m.Groups["group"].Value;
            //var item = ConfigurationManager.ConnectionStrings.Cast<ConnectionStringSettings>()
            //    .FirstOrDefault(c=>c.ConnectionString==connectionString);
            //return item.Name;
        }

        protected override DbProviderFactory DbProviderFactory {
            get { return ProxyProviderFactory.Instance; }
        }
    }
}
